﻿using System;
using System.Linq;
using Castle.Core.Logging;
using User.EF.Contracts;
using User.EF.Model;

namespace User.EF.Queries
{
    public class MembershipQueries : IMembershipQueries
    {
        #region Member
        /// <summary>
        /// Der Aktuelle ModelContext
        /// </summary>
        public MainModelContainer Context { get; private set; }

        /// <summary>
        /// Der Aktuelle Logger.
        /// </summary>
        public ILogger Logger { get; set; }
        #endregion

        public MembershipQueries(MainModelContainer context)
        {
            if (context == null)
            {
                throw  new Exception("UserQueries context is Null");
            }

            Context = context;
        }

        #region Implementation of IMembershipQueries
        /// <summary>
        /// Ermittelt den passenden User anhand des übergebenen UserNamens
        /// </summary>
        /// <param name="username">Der Username der gesucht werden soll</param>
        /// <returns>User | NULL wenn keiner gefunden wurde.</returns>
        public Member GetMemberByUsername(string username)
        {
            //Den User anhand seines Usernamens ermitteln
            var user = Context.MemberSet.FirstOrDefault(p => p.Username.ToLower() == username.Trim().ToLower());
            return user;
        }

        /// <summary>
        /// Ermittelt den passenden User anhand des übergebenen UserId
        /// </summary>
        /// <param name="userId">Die userId die gesucht werden soll</param>
        /// <returns>User | NULL wenn keiner gefunden wurde.</returns>
        public Member GetMemberById(long userId)
        {
            var user = Context.MemberSet.FirstOrDefault(p => p.Id == userId);
            return user;
        }

        /// <summary>
        /// Ermittelt den passenden User anhand des übergebenen Reset Tokens und prüft bereits das Expiration Date mit ab.
        /// </summary>
        /// <param name="resetToken">Der Token der gesucht werden soll</param>
        /// <returns>User | NULL wenn keiner gefunden wurde.</returns>
        public Member GetMemberByResetToken(string resetToken)
        {
            DateTime now = DateTime.Now;
            //Direkt nur nach einem Eintrag suchen wo auch das Expirationdate im übergebenen Zeitraum liegt.
            var user = Context.MemberSet.FirstOrDefault(p => p.PasswordVerificationToken.ToLower() == resetToken.Trim().ToLower() && now < p.PasswordVerifivationTokenExpirationDate);
            return user;
        }

        /// <summary>
        /// Fügt den übergebenen Member unserer Memberliste hinzu, wenn die UserId != 0 ist.
        /// </summary>
        /// <param name="member">Der Member der unserer Liste hinzugefügt werden soll</param>
        /// <returns></returns>
        public bool AddMember(Member member)
        {
            //Nur wenn dem Member noch keine ID zugeordnet wurde, diesen der Liste hinzufügen
            if(member.Id == 0)
            {
                //der Liste hinzufügen
                Context.MemberSet.Add(member);
                return true;
            }

            return false;
        }

        /// <summary>
        /// Speichern der Einstellungen
        /// </summary>
        /// <returns>TRUE->Speichern erfolgreich | FALSE->Fehler beim Speichern</returns>
        public bool Save()
        {
            try
            {
                Context.SaveChanges();
                return true;
            }
            catch (Exception exception)
            {
                Logger.Error("Save Exception Member", exception);
                return false;
            }
        }
        #endregion
    }
}